package com.mti.service.impl;

import java.io.IOException;
import java.io.OutputStream;
import java.util.Arrays;
import java.util.List;
import java.util.Map;

import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.mti.constant.ZdryHistoryLogType;
import com.mti.dao.dto.ZdryDto;
import com.mti.dao.model.SysDictEntity;
import com.mti.dao.vo.ZdryHistoryLogVo;
import com.mti.enums.RoleType;
import com.mti.exception.BusinessException;
import com.mti.jwt.AccountBo;
import com.mti.jwt.RequestUtils;
import com.mti.utils.ExeclUtil;
import com.mti.utils.JsonFileParseUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.poi.ss.usermodel.CellStyle;
import org.apache.poi.ss.usermodel.HorizontalAlignment;
import org.apache.poi.ss.usermodel.VerticalAlignment;
import org.apache.poi.xssf.streaming.SXSSFWorkbook;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.io.buffer.DataBuffer;
import org.springframework.core.io.buffer.DefaultDataBuffer;
import org.springframework.core.io.buffer.DefaultDataBufferFactory;
import org.springframework.stereotype.Service;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.mti.dao.model.LfZdryHistoryLogEntity;
import com.mti.dao.qo.HistoryLogQO;
import com.mti.mapper.LfZdryHistoryLogMapper;
import com.mti.service.LfZdryHistoryLogService;
import com.mti.service.TTaskFileService;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Mono;

/**
 * <p>
 *  服务实现类
 * </p>
 *
 * @author chenf
 * @since 2020-03-24
 */
@Slf4j
@Service
public class LfZdryHistoryLogServiceImpl extends ServiceImpl<LfZdryHistoryLogMapper, LfZdryHistoryLogEntity> implements LfZdryHistoryLogService {
	@Autowired
	private TTaskFileService taskFileService;
	@Autowired
	private RequestUtils requestUtils;
	
	@Override
	public List<LfZdryHistoryLogEntity> getByType(HistoryLogQO logqo) {
		QueryWrapper<LfZdryHistoryLogEntity> wrapper = new QueryWrapper<>();
		//如果查询全部传参数0
		if(0!=logqo.getType()) {
			wrapper.eq("type", logqo.getType());
		}
		wrapper.eq("sp_id", logqo.getZdryId());
        wrapper.orderByDesc("create_time").lambda().last("LIMIT "+logqo.getLimit());
        List<LfZdryHistoryLogEntity> historys =  this.list(wrapper);
		
		for (LfZdryHistoryLogEntity history : historys) {
			history.setFileList(taskFileService.getByBussId(history.getId()));
		}
        return historys;
	}

    @Override
    public IPage<ZdryHistoryLogVo> getZdryHistiryLog(HistoryLogQO logqo, ServerWebExchange exchange) {
		Page<ZdryHistoryLogVo> page = new Page<>(logqo.getStart(),logqo.getSize());
		setUpAuthority(exchange,logqo);
		IPage<ZdryHistoryLogVo> result = this.getBaseMapper().getZdryHistiryLog(page,logqo);
		return result;
    }

	@Override
	public Mono<DataBuffer> exportZdryHistoryLog(HistoryLogQO logqo, ServerWebExchange exchange) {
		DefaultDataBuffer dataBuffer = new DefaultDataBufferFactory().allocateBuffer();
		OutputStream outputStream = dataBuffer.asOutputStream();
		// 每次写100行数据，就刷新数据出缓存
		SXSSFWorkbook wb = new SXSSFWorkbook(100);
		try {
			CellStyle cellStyleCenter = wb.createCellStyle();
			CellStyle cellStyleLeft = wb.createCellStyle();
			cellStyleCenter.setAlignment(HorizontalAlignment.CENTER); // 居中
			cellStyleCenter.setVerticalAlignment(VerticalAlignment.CENTER); // 居中
			cellStyleLeft.setAlignment(HorizontalAlignment.LEFT);
			cellStyleLeft.setVerticalAlignment(VerticalAlignment.CENTER);
			//加载数据的地方
			setUpAuthority(exchange,logqo); //设置权限

			List<ZdryHistoryLogVo> zdryLoges = this.getBaseMapper().getExportZdryLogData(logqo);
			zdryLoges.forEach(e->{
				e.setTypeName(ZdryHistoryLogType.ZdryHistoryLogType.get(e.getType()));
			});
			Map<String,String> proTitleMap = JsonFileParseUtil.readJsonFromClassPath("json/zdryHistoryLog.json",Map.class);
			ExeclUtil.genExcel(wb,cellStyleCenter,cellStyleLeft,zdryLoges,ZdryHistoryLogVo.class,proTitleMap,"重点人员日志记录");
			wb.write(outputStream);
		} catch (Exception e) {
			log.error("导出execl时发生异常：======>{}",e.getMessage());
		}finally {
			try {
				wb.close();
				outputStream.flush();
				outputStream.close();
			} catch (IOException e) {

				log.error("关闭流时发生异常：======> {}",e.getMessage());
			}
		}
		return Mono.just(dataBuffer);
	}

	/**
	 *  重点人员log查询记录
	 * @param exchange
	 * @param logqo
	 */
	private void setUpAuthority(ServerWebExchange exchange,HistoryLogQO logqo) {
		try {
			// 权限相关代码
			AccountBo bo = requestUtils.getCurrentUser(exchange);
			if (bo == null) {
				throw new BusinessException(10019,"此账号已在别处登录，请查证");
			}
			String roleType = bo.getRoleList().get(0).getRoleType();
			String orgName = bo.getOrganizationBo().getShortName();
			String orgId = bo.getOrganizationBo().getId();
            /* getOrgName(bo.getOrgId());
             1、管理员、市局情报中心,不加判断条件
             2、市局各警种
             角色类型："管理员", "0")"市局情报中心", "1"), "市局警种", "2"),"分局", "3"),"派出所", "4")
             审批状态：0：待分局审批,1：待警种审核,2：已驳回,3：已完成, 4：上报
             对应的列表参数 zrbmList:警种;  zrfj :分局;  zrmj:民警;  sspcsList:派出所.
             */
			if (roleType.equals(RoleType.OWNER_ADMIN_ORG_DATA.getType())) { // 1:市局情报中心
				//qo.setSsxqList(qo.getQueryList());
			} else if (roleType.equals(RoleType.OWNER_REVIEW_DATA.getType())
					|| roleType.equals(RoleType.OWNER_ORG_DATA.getType())) { // 5:市局警种和2:市局警种审核
				if(null == logqo.getZrbmList() || logqo.getZrbmList().size()==0){
					logqo.setZrbmList(Arrays.asList(orgName));
				}
			} else if (roleType.equals(RoleType.BREACH_REVIEW_DATA.getType())
					|| roleType.equals(RoleType.BREACH_DATA.getType())) { // 6:分局 和 3:分局审核
				if(null == logqo.getZrfj() || logqo.getZrfj().size()==0){
					logqo.setZrfj(Arrays.asList(orgId));
				}
			} else if (roleType.equals(RoleType.POLICE_STATION_DATA.getType())) { // 派出所4
				if(null == logqo.getSspcsList() || logqo.getSspcsList().size()==0){
					logqo.setSspcsList(Arrays.asList(orgId));
				}
			}

		} catch (BusinessException e) {
			log.error("权限参数异常或者筛选参数异常：======>{}",e.getMessage());
			if("此账号已在别处登录，请查证".equals(e.getMessage())){
				throw new BusinessException(10019,"此账号已在别处登录，请查证");
			}
		}
	}

}
